home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
nxyplot
/
Source
/
ColumnSelectionHandler.m
< prev
next >
Wrap
Text File
|
1992-07-20
|
12KB
|
365 lines
/* Generated by Interface Builder */
#import "ColumnSelectionHandler.h"
#import "Plot.h"
#import "defs.h"
#import <appkit/Font.h>
#import <appkit/Panel.h>
#import <appkit/Window.h>
#import <appkit/Matrix.h>
#import <appkit/View.h>
#import <appkit/ButtonCell.h>
#import <dpsclient/wraps.h>
#import <appkit/color.h> /* only for "blanking out" parts of a matrix */
#import <appkit/graphics.h> /* ditto */
/*
* The job of this object is to keep the appearance of the Column Selection panel
* in accord with the state of the program. We do not update the Column Selection
* panel every time a file is read in, since it is expected that this option will
* not be heavily used.
*/
@implementation ColumnSelectionHandler
- init
{
/*
* This global variable keeps track of whether the column selection window
* has ever been displayed. We can avoid updating after the selective
* file removal if we have never been displayed.
*/
everVisible = NO;
return self;
}
/*
* Arrange to blank out the disabled buttons. The "right" way to do this
* is probably to have a "RaggedMatrix" class which allows a different
* number of columns in each row, but there are too many other issues
* raised by that to deal with right now. Note that having such a class
* would allow us to correctly deal with the problem of correctly
* redisplaying the matrix after a resize operation on the window.
* (We currently get around that problem by making ourself the window's delegate
* and defining windowDidResize:, and in that method calling
* perform:with:afterDelay:cancelPrevious, but this is highly suboptimal.)
*/
- eraseDisabledCells:sender
{
int n, j, numrows, numcols, ncurves;
NXRect r;
[columnMatrix getNumRows:&numrows numCols:&numcols];
[columnMatrix lockFocus];
NXSetColor([columnMatrix backgroundColor]);
/* The NXSetColor call has to come after the lockFocus; otherwise, when
* this method is called by fixPanel, the color always comes out black
* even if something else is specifically requested. The weird part is,
* when this method is called by fixRow, the color is correct when the
* NXSetColor call is outside the lockFocus.
*/
for (n=0; n<[plotParam nFiles]; n++) {
ncurves = [plotParam nCurves:n];
if (ncurves < numcols-1) {
for (j=ncurves; j<numcols; j++) {
[columnMatrix getCellFrame:&r at:n :j+1]; /* note the j+1 */
NXRectFill(&r);
}
}
}
[columnMatrix unlockFocus];
NXPing();
return self;
}
- removeAll:sender
/* This method is called by the "remove all files" method of the Plot object. */
{
int n, j;
int numrows, numcols;
NXSize cellsize, intercell;
NXCoord dy;
/* Do something only if the window has ever been displayed */
if (everVisible) {
[columnMatrix getNumRows:&numrows numCols:&numcols];
[columnMatrix getCellSize:&cellsize];
[columnMatrix getIntercell:&intercell];
/*
* Wipe out everything.
*/
dy = (NXCoord)(numrows - 1) * (cellsize.height + intercell.height);
[columnMatrix moveBy:0.0 :dy];
/*
* Before doing renewRows, set the state of all the cells to 0; this is
* because the renewRows method just recycles the cells, and later on
* we may find ourselves using a cell which has state=1 when we don't
* want such a beast. Also enable all cells (paranoia strikes).
*/
for (n=0; n<numrows; n++) {
for (j=0; j<numcols; j++) {
[[columnMatrix cellAt:n :j] setState:0];
[[columnMatrix cellAt:n :j] setEnabled:YES];
}
}
[columnMatrix renewRows:1 cols:1];
[columnMatrix sizeToCells];
[[columnMatrix cellAt:0 :0] setEnabled:YES];
[[columnMatrix cellAt:0 :0] setType:NX_TOGGLE];
[[columnMatrix cellAt:0 :0] setState:1];
[filenameMatrix moveBy:0.0 :dy];
[filenameMatrix renewRows:1 cols:1];
[[filenameMatrix cellAt:0 :0] setStringValue:"filename"];
[filenameMatrix sizeToCells];
[columnText renewRows:1 cols:1];
[columnText sizeToCells];
/* Do some drawing now. Display the view. */
[[columnMatrix window] display];
NXPing(); /* needed??? */
}
return self;
}
- fixPanel:sender
/*
* The select column button activates this method; it is also called from
* windowDidResize, from Plot.m in postludeToReading, and by the update
* button on the panel. We have to fix up the column selection panel
* so that it's correct.
*/
{
int n, j;
int nfilestotal = [plotParam nFiles], maxcols = 0, ncurves;
char title[80];
int numrows, numcols;
BOOL one_on;
NXSize cellsize, intercell;
NXCoord dy;
int * turned_on;
if (everVisible == NO) everVisible = YES;
[columnMatrix getNumRows:&numrows numCols:&numcols];
[columnMatrix getCellSize:&cellsize];
[columnMatrix getIntercell:&intercell];
/*
* We have to create some additional rows and perhaps some additional columns.
*/
// First figure out how many rows and columns the matrices should have
for (n=0; n<nfilestotal; n++) {
maxcols = MAX(maxcols, [plotParam nCurves:n]);
}
maxcols++; /* this is the number of columns needed */
if (numrows != nfilestotal || numcols != maxcols) {
/* The renewRows:cols: message might have the side effect of setting
* the state of all the cells of the matrix back to 0; this is undesired,
* so before changing the number of rows and/or columns in the matrix,
* make sure we remember which cells in each row were turned on.
*/
turned_on = (int *)malloc(numrows * sizeof(int)); /* should do error check */
for (n=0; n<numrows; n++) {
turned_on[n] = 0; /* cautious initialization */
for (j=0; j<numcols; j++) {
if ([[columnMatrix cellAt:n :j] state] == 1) {
turned_on[n] = j;
break;
}
}
}
[columnMatrix renewRows:nfilestotal cols:maxcols];
for (n=numrows; n<nfilestotal; n++) {
[[columnMatrix cellAt:n :0] setState:1];
for (j=1; j<maxcols; j++) {
[[columnMatrix cellAt:n :j] setState:0];
}
}
/* And now turn cells back on. */
for (n=0; n<numrows; n++) {
for (j=0; j<numcols; j++) {
[[columnMatrix cellAt:n :j] setState:0];
}
[[columnMatrix cellAt:n :turned_on[n]] setState:1];
}
free((void *)turned_on);
}
[columnMatrix sizeToCells];
dy = (float)(nfilestotal - numrows) * (cellsize.height + intercell.height);
[columnMatrix moveBy:0.0 :-dy];
// Some of the cells may come in with type NULLCELL; fix them here
for (n=0; n<nfilestotal; n++) {
for (j=0; j<maxcols; j++) {
[[columnMatrix cellAt:n :j] setEnabled:YES];
[[columnMatrix cellAt:n :j] setType:NX_TOGGLE];
}
}
// Make sure exactly one button is turned on in each row
for (n=0; n<nfilestotal; n++) {
one_on = NO;
for (j=0; j<maxcols; j++) {
if ([[columnMatrix cellAt:n :j] state] == 1) {
one_on = YES;
break;
}
}
if (!one_on)
[[columnMatrix cellAt:n :0] setState:1];
}
// We surround the [columnMatrix display] and [self eraseDisabledCells]
// calls with the disableFlushWindow, reenableFlushWindow, and flushWindow
// calls to prevent the disabled matrix cells from being visible for a long
// time while they're drawn and then erased.
[columnPanel disableFlushWindow];
[columnMatrix display];
// Disable cells that shouldn't appear.
for (n=0; n<nfilestotal; n++) {
ncurves = [plotParam nCurves:n];
if (ncurves < maxcols-1) {
for (j=ncurves; j<maxcols; j++) {
[[columnMatrix cellAt:n :j+1] setType:NX_NULLCELL]; /* note the j+1 */
[[columnMatrix cellAt:n :j+1] setEnabled:NO]; /* again j+1 */
}
}
}
// We have to put the makeKeyAndOrderFront before the eraseDisabledCells
// method, because eraseDisabledCells does a lockFocus and lockFocus needs
// a real window to draw into. We put the makeKeyAndOrderFront here rather
// than at the beginning of this method because this way the disabled cells
// of the matrix are visible for a shorter period of time.
[columnPanel makeKeyAndOrderFront:self];
// Now erase those disabled cells.
[self eraseDisabledCells:self];
[columnPanel reenableFlushWindow];
[columnPanel flushWindowIfNeeded];
NXPing(); /* needed? */
// That finishes with the columnMatrix; now for the filename Matrix.
[filenameMatrix renewRows:nfilestotal cols:1];
for (n=0; n<nfilestotal; n++) {
if (!strncmp([plotParam filename:(unsigned)n], "pasteboard", 10))
sprintf(title, "pasteboard");
else
sprintf(title, strrchr([plotParam filename:(unsigned)n], '/') + 1);
[[filenameMatrix cellAt:n :0] setStringValue:title];
}
[filenameMatrix sizeToCells];
[filenameMatrix moveBy:0.0 :-dy];
[filenameMatrix display];
// And now for the columnText matrix.
[columnText renewRows:1 cols:maxcols];
for (j=1; j<=maxcols; j++) {
sprintf(title, "%d", j);
[[columnText cellAt:0 :(j-1)] setStringValue:title];
}
[columnText sizeToCells];
[columnText display];
return self;
}
- fixRow:sender
/* The sender is columnMatrix in the column selection panel; we want to
* turn off some buttons in the matrix row.
*/
{
int row, col, i, prev_col=0, numrows, numcols;
row = [sender selectedRow];
col = [sender selectedCol];
[sender getNumRows:&numrows numCols:&numcols];
// Find out what column was previously highlighted:
for (i=0; i<numcols; i++) {
if ( [[sender cellAt:row :i] state] == 1 && i != col) {
prev_col = i;
break;
}
}
// adjust the matrix
for (i=0; i<numcols; i++) {
[ [sender cellAt:row :i] setState:0];
}
[ [sender cellAt:row :col] setState:1];
// The disableFlushWindow, reenableFlushWindow, and flushWindow methods
// bracket the [sender display] and [self eraseDisabledCells] methods, with
// the result that the disabled cells are not visibly drawn on the screen.
// This is the way it should be.
[columnPanel disableFlushWindow];
[sender display];
[self eraseDisabledCells:self];
[columnPanel reenableFlushWindow];
[columnPanel flushWindowIfNeeded];
// swap the pointers as requested
[plotParam swapColumns:prev_col :col forFileNumber:row];
return self;
}
/*
* We call fixPanel here, rather than eraseDisabledCells (which is more
* logical), because for some reason eraseDisableCells doesn't seem to work
* properly! The method fixPanel: does a lot more work than is really
* needed. Sigh... This should all be cleaned up.
*/
- windowDidResize:sender
{
[self perform:@selector(fixPanel:)
with:self
afterDelay:1 /* wait 0.001 second */
cancelPrevious:YES];
return self;
}
/*
* This is called by the selective file removal code in Plot.m.
*/
- update:sender
{
int n, nfilestotal = [plotParam nFiles], num_removed = 0;
NXSize cellsize, intercell;
NXCoord dy;
/* Do something only if the window has ever been displayed */
if (everVisible) {
[columnMatrix getCellSize:&cellsize];
[columnMatrix getIntercell:&intercell];
/*
* Count down the file removal panel, removing rows as needed.
*/
for (n = nfilestotal-1; n>=0; n--) {
if ([[fileRemovalButtons cellAt:n :0] state] == 1) {
/* This file is to be removed. */
num_removed++;
[columnMatrix removeRowAt:n andFree:YES];
[filenameMatrix removeRowAt:n andFree:YES];
}
}
[columnMatrix sizeToCells];
[filenameMatrix sizeToCells];
if (num_removed > 0) {
dy = (NXCoord)(num_removed) * (cellsize.height + intercell.height);
[columnMatrix moveBy:0.0 :dy];
[filenameMatrix moveBy:0.0 :dy];
}
/* Do some drawing now. Display the view. */
[[columnMatrix window] display];
NXPing(); /* needed??? */
}
return self;
}
@end